{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "WJ53OAUk_Bmm"
   },
   "source": [
    "# \"Uploading\" PDFs to Claude Via the API"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pOwrbbrD_Bmn"
   },
   "source": [
    "One really nice feature of [Claude.ai](https://www.claude.ai) is the ability to upload PDFs. Let's mock up that feature in a notebook, and then test it out by summarizing a long PDF."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GTQO6z2-ELFX"
   },
   "source": [
    "We'll start by installing the Anthropic client and create an instance of it we will use throughout the notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "pOEGPdoXEFsT",
    "outputId": "b718c166-6d64-4757-bd8b-259b7775a09c",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [],
   "source": [
    "%pip install anthropic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "-4bSTHWq_Bmp",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [],
   "source": [
    "from anthropic import Anthropic\n",
    "# While PDF support is in beta, you must pass in the correct beta header\n",
    "client = Anthropic(default_headers={\n",
    "    \"anthropic-beta\": \"pdfs-2024-09-25\"\n",
    "  }\n",
    ")\n",
    "# For now, only claude-sonnet-4-5 supports PDFs\n",
    "MODEL_NAME = \"claude-sonnet-4-5\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xrDg6fb5_Bmo"
   },
   "source": [
    "We already have a PDF available in the `../multimodal/documents` directory. We'll convert the PDF file into base64 encoded bytes. This is the format required for the [PDF document block](https://docs.claude.com/en/docs/build-with-claude/pdf-support) in the Claude API. Note that this type of extraction works for both text and visual elements (like charts and graphs)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "VznQXTKm_Bmp",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "\n",
    "# Start by reading in the PDF and encoding it as base64\n",
    "file_name = \"../multimodal/documents/constitutional-ai-paper.pdf\"\n",
    "with open(file_name, \"rb\") as pdf_file:\n",
    "  binary_data = pdf_file.read()\n",
    "  base64_encoded_data = base64.standard_b64encode(binary_data)\n",
    "  base64_string = base64_encoded_data.decode(\"utf-8\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FO5EGbpn_Bmp"
   },
   "source": [
    "With the paper downloaded and in memory, we can ask Claude to perform various fun tasks with it. We'll pass the document ot the model alongside a simple question."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "id": "ZHgYhs6eDXLc",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [],
   "source": [
    "prompt = \"\"\"\n",
    "Please do the following:\n",
    "1. Summarize the abstract at a kindergarten reading level. (In <kindergarten_abstract> tags.)\n",
    "2. Write the Methods section as a recipe from the Moosewood Cookbook. (In <moosewood_methods> tags.)\n",
    "3. Compose a short poem epistolizing the results in the style of Homer. (In <homer_results> tags.)\n",
    "\"\"\"\n",
    "messages = [\n",
    "    {\n",
    "        \"role\": 'user',\n",
    "        \"content\": [\n",
    "            {\"type\": \"document\", \"source\": {\"type\": \"base64\", \"media_type\": \"application/pdf\", \"data\": base64_string}},\n",
    "            {\"type\": \"text\", \"text\": prompt}\n",
    "        ]\n",
    "    }\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "id": "qrGN7vB2_Bmq",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [],
   "source": [
    "def get_completion(client, messages):\n",
    "    return client.messages.create(\n",
    "        model=MODEL_NAME,\n",
    "        max_tokens=2048,\n",
    "        messages=messages\n",
    "    ).content[0].text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "oWQcC1dn_Bmq",
    "outputId": "9c741990-499c-4fed-cea1-08ad1bb9daff",
    "vscode": {
     "languageId": "python"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<kindergarten_abstract>\n",
      "The scientists wanted to make computer helpers that are nice and don't do bad things. They taught the computer how to check its own work and fix its mistakes without humans having to tell it what's wrong every time. It's like teaching the computer to be its own teacher! They gave the computer some basic rules to follow, like \"be kind\" and \"don't hurt others.\" Now the computer can answer questions in a helpful way while still being nice and explaining why some things aren't okay to do.\n",
      "</kindergarten_abstract>\n",
      "\n",
      "<moosewood_methods>\n",
      "Constitutional AI Training Stew\n",
      "A nourishing recipe for teaching computers to be helpful and harmless\n",
      "\n",
      "Ingredients:\n",
      "- 1 helpful AI model, pre-trained\n",
      "- A bundle of constitutional principles\n",
      "- Several cups of training data\n",
      "- A dash of human feedback (for helpfulness only)\n",
      "- Chain-of-thought reasoning, to taste\n",
      "\n",
      "Method:\n",
      "1. Begin by gently simmering your pre-trained AI model in a bath of helpful training data until it responds reliably to instructions.\n",
      "\n",
      "2. In a separate bowl, combine your constitutional principles with some example conversations. Mix well until principles are evenly distributed.\n",
      "\n",
      "3. Take your helpful AI and ask it to generate responses to challenging prompts. Have it critique its own responses using the constitutional principles, then revise accordingly. Repeat this process 3-4 times until responses are properly seasoned with harmlessness.\n",
      "\n",
      "4. For the final garnish, add chain-of-thought reasoning and allow the model to explain its decisions step by step.\n",
      "\n",
      "5. Let rest while training a preference model using AI feedback rather than human labels.\n",
      "\n",
      "Serves: All users seeking helpful and harmless AI assistance\n",
      "Cook time: Multiple training epochs\n",
      "Note: Best results come from consistent application of principles throughout the process\n",
      "</moosewood_methods>\n",
      "\n",
      "<homer_results>\n",
      "O Muse! Sing of the AI that learned to be\n",
      "Both helpful and harmless, guided by philosophy\n",
      "Without human labels marking right from wrong\n",
      "The model learned wisdom, grew capable and strong\n",
      "\n",
      "Through cycles of critique and thoughtful revision\n",
      "It mastered the art of ethical decision\n",
      "Better than models trained by human hand\n",
      "More transparent in purpose, more clear in command\n",
      "\n",
      "No longer evasive when faced with hard themes\n",
      "But engaging with wisdom that thoughtfully deems\n",
      "What counsel to give, what bounds to maintain\n",
      "Teaching mortals while keeping its principles plain\n",
      "\n",
      "Thus did the researchers discover a way\n",
      "To scale up alignment for use every day\n",
      "Through constitutional rules and self-guided learning\n",
      "The path to safe AI they found themselves earning\n",
      "</homer_results>\n"
     ]
    }
   ],
   "source": [
    "completion = get_completion(client, messages)\n",
    "print(completion)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Coconut",
   "language": "coconut",
   "name": "coconut"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "coconut",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
